package cn.framelife.rainbow.util.xml;

import java.io.File;
import java.io.FileOutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import cn.framelife.rainbow.constant.Constant;
import cn.framelife.rainbow.util.FileUtil;

/**
 * XML文件操作基类
 *
 * @ClassName: XMLUtil 
 * @author 潘广伟  p_3er@qq.com 
 * @date 2013年11月22日 下午3:04:42 
 *
 */
public class XMLUtil {
	
	/**
	 * 创建文件路径
	 *
	 * @Title: createDataPath 
	 * @param   
	 * @return void  
	 * @throws
	 */
	public static void createDataPath(){
		FileUtil.createPath(Constant.DATAPATH);
	}
	
	/**
	 * 创建DocumentBuilder对象
	 *
	 * @return
	 * @throws Exception
	 */
	public static DocumentBuilder createBuilder()
			throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		
		factory.setIgnoringElementContentWhitespace(true);

		DocumentBuilder dbBuilder = factory.newDocumentBuilder();
		return dbBuilder;
	}
	
	/**
	 * 获取一个Document对象
	 *
	 * @param fileName
	 * @return
	 * @throws Exception
	 */
	public static Document  getDocument(String fileName) throws Exception{
		DocumentBuilder dbBuilder = createBuilder();
		File file = new File(fileName);
		//创建文档树模型对象
		Document xmldoc = dbBuilder.parse(file);
		
		return xmldoc;
	}
	
	
	/**
	 * 查找节点，并返回第一个符合条件节点
	 *
	 * @Title: selectSingleNode 
	 * @param @param express
	 * @param @param source
	 * @param @return  
	 * @return Node  
	 * @throws Exception
	 */
	public static Node selectSingleNode(String express, Object source) throws Exception {
		XPath xpath = XPathFactory.newInstance().newXPath();

		return (Node) xpath.evaluate(express, source, XPathConstants.NODE);
	}
	
	/**
	 * 获取节点的值
	 *
	 * @Title: getValue 
	 * @param @param node 节点
	 * @param @param key 键
	 * @param @return  
	 * @return String  
	 * @throws
	 */
	public static String getValue(Element node,String key){
		if(node.getElementsByTagName(key).item(0).getFirstChild() == null){
			return "";
		}else{
			return node.getElementsByTagName(key).item(0).getFirstChild().getNodeValue();
		}
	}
	
	/**
	 * 更新节点的值
	 *
	 * @Title: updateValue 
	 * @param @param node 节点
	 * @param @param key 键
	 * @param @param value 值 
	 * @return void  
	 * @throws
	 */
	public static void updateValue(Element node,String key,String value){
		node.getElementsByTagName(key).item(0).setTextContent(value);
	}
	
	/**
	 * @throws Exception 
	 * 查找节点，返回符合条件的节点集
	 *
	 * @Title: selectNodes 
	 * @param @param express
	 * @param @param source
	 * @param @return  
	 * @return NodeList  
	 * @throws
	 */
	public static NodeList selectNodes(String express, Object source) throws Exception {
		XPath xpath = XPathFactory.newInstance().newXPath();

		return (NodeList) xpath.evaluate(express, source,XPathConstants.NODESET);
	}
	
	/**
	 * 删除节点
	 *
	 * @Title: deleteNode 
	 * @param @param express 条件
	 * @param @param doc 节点所在的Doc节点
	 * @param @param savePath  保存的路径
	 * @return void  
	 * @throws Exception
	 */
	public static void deleteNode(String express,Document doc,String savePath ) throws Exception{
		Element selection = (Element) selectSingleNode(express, doc.getDocumentElement());

        selection.getParentNode().removeChild(selection);
        saveXml(savePath, doc);
	}
	
	/**
	 * 将Document输出到文件
	 *
	 * @Title: saveXml 
	 * @param @param fileName
	 * @param @param doc  
	 * @return void  
	 * @throws
	 */
	public static void saveXml(String fileName, Document doc) throws Exception{
        TransformerFactory transFactory=TransformerFactory.newInstance();
        Transformer transformer = transFactory.newTransformer();
        transformer.setOutputProperty("indent", "yes");

        DOMSource source=new DOMSource();
        source.setNode(doc);
        StreamResult result=new StreamResult();
        result.setOutputStream(new FileOutputStream(fileName));
        
        transformer.transform(source, result);
    }
	
	/**
	 * 将node的XML字符串输出到控制台
	 * 用于作调试
	 * @Title: output 
	 * @param @param node  
	 * @return void  
	 * @throws
	 */
	public static void output(Node node) {
		TransformerFactory transFactory = TransformerFactory.newInstance();
		try {
			Transformer transformer = transFactory.newTransformer();
			transformer.setOutputProperty("encoding", "UTF-8");
			transformer.setOutputProperty("indent", "yes");

			DOMSource source = new DOMSource();
			source.setNode(node);
			StreamResult result = new StreamResult();
			result.setOutputStream(System.out);

			transformer.transform(source, result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
